/*
 * Copyright (C) 2004, Velocityme Partnership
 * SearchActions.java
 *
 * Created on 02 October 2004, 07:10
 */

package com.velocityme.www.interfaces;

import com.velocityme.entity.Activity;
import com.velocityme.entity.Node;
import com.velocityme.session.ContactableLocal;
import com.velocityme.session.KeyLocal;
import com.velocityme.session.NodeLocal;
import com.velocityme.session.SearchLocal;
import com.velocityme.utility.NodeSearchResult;
import com.velocityme.www.actionforms.AdvancedSearchActionForm;
import com.velocityme.www.actionforms.SearchDateActionForm;
import com.velocityme.www.actionforms.SearchOthersResponsibilityActionForm;
import com.velocityme.www.actionforms.SearchReportActionForm;
import com.velocityme.www.dto.IdName;
import com.velocityme.www.dto.SearchReportDTO;
import com.velocityme.www.utility.NodeUtil;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.swing.tree.TreeModel;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

/**
 *
 * @author  Robert
 */
public class SearchActions extends DispatchAction {
    
    /** Creates a new instance of SearchActions */
    public SearchActions() {
    }
    
    public ActionForward showLastWeekTasks(ActionMapping mapping, 
                                           ActionForm form,
                                           HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        SearchDateActionForm searchDateAF = new SearchDateActionForm();
        Calendar lastWeek = Calendar.getInstance();
        lastWeek.add(Calendar.WEEK_OF_YEAR, -1);
        searchDateAF.setNodeId(nodeId);
        searchDateAF.setStartDate(lastWeek);
        return showNewTasks(mapping, searchDateAF, request, response);
    }
    
    public ActionForward showNewTasks(ActionMapping mapping, 
                                      ActionForm form,
                                      HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        SearchDateActionForm searchDateAF = (SearchDateActionForm)form;
        Long nodeId = searchDateAF.getNodeId();
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Calendar date = searchDateAF.getStartDate();
        session.setAttribute("resultValues", lookupSearchBean().findParameterSearch(key, nodeId, new HashSet<Long>(), new HashSet<String>(), date.getTime(), null, new HashSet<Long>(), new HashSet<Long>()));
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("searchDateActionForm", searchDateAF);
        return mapping.findForward("ACTION_DISPLAY_NEW_TASKS");
    }
    
    public ActionForward showCompletedLastWeekTasks(ActionMapping mapping, 
                                           ActionForm form,
                                           HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        SearchDateActionForm searchDateAF = new SearchDateActionForm();
        Calendar lastWeek = Calendar.getInstance();
        lastWeek.add(Calendar.WEEK_OF_YEAR, -1);
        searchDateAF.setNodeId(nodeId);
        searchDateAF.setStartDate(lastWeek);
        return showCompletedTasks(mapping, searchDateAF, request, response);
    }
    
    public ActionForward showCompletedTasks(ActionMapping mapping, 
                                            ActionForm form,
                                            HttpServletRequest request,
                                            HttpServletResponse response) throws Exception {
        SearchDateActionForm searchDateAF = (SearchDateActionForm)form;
        Long nodeId = searchDateAF.getNodeId();
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Calendar date = searchDateAF.getStartDate();
        session.setAttribute("resultValues", lookupSearchBean().findCompletedTasks(key, nodeId, date.getTime()));
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("searchDateActionForm", searchDateAF);
        return mapping.findForward("ACTION_DISPLAY_COMPLETED_TASKS");
    }
    
    public ActionForward showChangedTodayTasks(ActionMapping mapping, 
                                               ActionForm form,
                                               HttpServletRequest request,
                                               HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        SearchDateActionForm searchDateAF = new SearchDateActionForm();
        searchDateAF.setNodeId(nodeId);
        Calendar lastWeek = Calendar.getInstance();
        lastWeek.add(Calendar.WEEK_OF_YEAR, -1);
        searchDateAF.setStartDate(lastWeek);
        Calendar today = Calendar.getInstance();
        searchDateAF.setStopDate(today);
        return showChangedTasks(mapping, searchDateAF, request, response);
    }
    
    public ActionForward showChangedTasks(ActionMapping mapping, 
                                          ActionForm form,
                                          HttpServletRequest request,
                                          HttpServletResponse response) throws Exception {
        SearchDateActionForm searchDateAF = (SearchDateActionForm)form;
        Long nodeId = searchDateAF.getNodeId();
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Calendar startDate = searchDateAF.getStartDate();
        Calendar stopDate = searchDateAF.getStopDate();
        session.setAttribute("resultValues", lookupSearchBean().findChangedTasks(key, nodeId, startDate.getTime(), stopDate.getTime()));
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("searchDateActionForm", searchDateAF);
        return mapping.findForward("ACTION_DISPLAY_CHANGED_TASKS");
    }
    
    public ActionForward showOthersResponsibleTasksSetup(ActionMapping mapping,
                                                         ActionForm form,
                                                         HttpServletRequest request,
                                                         HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        session.setAttribute("contactablePairs", NodeUtil.getAllContactablePairs(key));
        // setup default values
        SearchOthersResponsibilityActionForm actionForm = new SearchOthersResponsibilityActionForm();
        actionForm.setNodeId(nodeId);
        session.setAttribute("actionForm", actionForm);
        return mapping.findForward("ACTION_SHOW_OTHERS_RESPONSIBLE_TASKS_SETUP");
    }
    
    public ActionForward showOthersResponsibleTasksSearchReport(ActionMapping mapping,
                                                                ActionForm form,
                                                                HttpServletRequest request,
                                                                HttpServletResponse response) throws Exception {
        SearchOthersResponsibilityActionForm actionForm = (SearchOthersResponsibilityActionForm)form;
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = actionForm.getNodeId();
        if (request.getParameter("btnSubmit").equals("OK")) {
            Collection<Long> contactableIds = actionForm.getContactableIds();
            boolean includeDescendents = actionForm.getIncludeDescendents();
            session.setAttribute("resultValues", lookupSearchBean().findContactablesResponsibleTasks(key, nodeId, contactableIds, includeDescendents));
            return mapping.findForward("ACTION_OK");
        }
        // Cancel simply displays the original node again
        else {
            request.setAttribute("nodePK", nodeId);
            return mapping.findForward("ACTION_CANCEL");
        }
    }
    
    public ActionForward showAdvancedSearchSetup(ActionMapping mapping, 
                                                 ActionForm form,
                                                 HttpServletRequest request,
                                                 HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodePK");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("statusPairs", NodeUtil.getAllStatusPairs(key));
        Collection<IdName> contactablePairs = new ArrayList<IdName>();
        TreeModel contactableTreeModel = lookupContactableBean().getContactableTree(key);
        NodeUtil.recursiveAddContactable(contactableTreeModel, contactableTreeModel.getRoot(), contactablePairs, 0);
        session.setAttribute("contactablePairs", contactablePairs);
        // setup default values
        Calendar now = Calendar.getInstance();
        AdvancedSearchActionForm advancedSearchAF = new AdvancedSearchActionForm();
        advancedSearchAF.setNodeId(nodeId);
        advancedSearchAF.setStartYear(now.get(Calendar.YEAR));
        advancedSearchAF.setStartMonth(now.get(Calendar.MONTH));
        advancedSearchAF.setStartDay(now.get(Calendar.DATE));
        advancedSearchAF.setStopYear(now.get(Calendar.YEAR));
        advancedSearchAF.setStopMonth(now.get(Calendar.MONTH));
        advancedSearchAF.setStopDay(now.get(Calendar.DATE));
        session.setAttribute("advancedSearchActionForm", advancedSearchAF);
        return mapping.findForward("ACTION_DISPLAY_SETUP");
    }
    
    public ActionForward showAdvancedSearchReport(ActionMapping mapping,
                                                  ActionForm form,
                                                  HttpServletRequest request,
                                                  HttpServletResponse response) throws Exception {
        AdvancedSearchActionForm advancedSearchAF = (AdvancedSearchActionForm)form;
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = advancedSearchAF.getNodeId();
        if (request.getParameter("btnSubmit").equals("OK")) {
            Set<Long> ids = advancedSearchAF.getIdList();
            Set<String> keywords = advancedSearchAF.getKeywordsArray();
            Date start = advancedSearchAF.getStartDate();
            Date stop = advancedSearchAF.getStopDate();
            Set<Long> statusIds = advancedSearchAF.getStatusIds();
            Set<Long> contactableIds = advancedSearchAF.getContactableIds();
            session.setAttribute("resultValues", lookupSearchBean().findParameterSearch(key, nodeId, ids, keywords, start, stop, statusIds, contactableIds));
            return mapping.findForward("ACTION_DISPLAY_ADVANCED_SEARCH_RESULTS");
        }
        // Cancel simply displays the original node again
        else {
            request.setAttribute("nodeId", nodeId);
            return mapping.findForward("ACTION_CANCEL");
        }
    }
    
/*    public ActionForward showReport(ActionMapping mapping,
                                    ActionForm form,
                                    HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {
        SearchReportActionForm searchReportAF = (SearchReportActionForm)form;
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = (Long)session.getAttribute("nodeId");
        Node node = lookupNodeBean().findNode(key, nodeId);
        Collection resultsValues = (Collection)session.getAttribute("resultValues");
        Integer taskCount = new Integer(resultsValues.size());
        Collection searchEntries = lookupSearchBean().searchReportValue(key,
                                                        nodeId,
                                                        resultsValues,
                                                        searchReportAF.getIncludeStateChanges(),
                                                        searchReportAF.getIncludeComments(),
                                                        searchReportAF.getIncludeResponsibility());
        SearchReportDTO searchReportDTO = new SearchReportDTO(node.getPathName(),
                                                              new Date(),
                                                              taskCount,
                                                              searchEntries);
        session.setAttribute("searchReportDTO", searchReportDTO);
        return mapping.findForward("ACTION_REPORT_SUCCESS");
    }*/
    
    private void calcDirection(HttpServletRequest request,
                               String sortColumn) {
        HttpSession session = request.getSession();
        int sortDirection;
        if (sortColumn.equals(session.getAttribute("sortColumn"))) {
            sortDirection = ((Integer)session.getAttribute("sortDirection")).intValue();
	    switch(sortDirection) {
                case -1: sortDirection = 1; break;
                case 1: sortDirection = -1; break;
            }
        }
        else {
            session.setAttribute("sortColumn", sortColumn);
            sortDirection = 1;
        }
        session.setAttribute("sortDirection", new Integer(sortDirection));
    }
    
    private int sortDirection(HttpServletRequest request) {
        return ((Integer)request.getSession().getAttribute("sortDirection")).intValue();
    }
    
    private ActionForward sortResults(ActionMapping mapping,
                                      HttpServletRequest request,
                                      Comparator comparator) {
        HttpSession session = request.getSession();
        List resultValues = new ArrayList((Collection)session.getAttribute("resultValues"));
        Collections.sort(resultValues, comparator);
        session.setAttribute("resultValues", resultValues);
        return mapping.findForward("ACTION_OK");
    }
    
    public ActionForward sortId(ActionMapping mapping,
                                ActionForm form,
                                final HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        calcDirection(request, "id");
        return sortResults(mapping, request, new Comparator<Activity>() {
            public int compare(Activity o1, Activity o2) {
                return o1.getId().compareTo(o2.getId()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortPriority(ActionMapping mapping,
                                      ActionForm form,
                                      final HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        calcDirection(request, "priority");
        return sortResults(mapping, request, new Comparator<Activity>() {
            public int compare(Activity o1, Activity o2) {
                return new Integer(o1.getPriority()).compareTo(new Integer(o2.getPriority())) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortPercent(ActionMapping mapping,
                                     ActionForm form,
                                     final HttpServletRequest request,
                                     HttpServletResponse response) throws Exception {
        calcDirection(request, "percent");
        return sortResults(mapping, request, new Comparator<Activity>() {
            public int compare(Activity o1, Activity o2) {
                return new Integer(o1.getPercentageComplete()).compareTo(new Integer(o2.getPercentageComplete())) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortName(ActionMapping mapping,
                                  ActionForm form,
                                  final HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        calcDirection(request, "name");
        return sortResults(mapping, request, new Comparator<Activity>() {
            public int compare(Activity o1, Activity o2) {
                return o1.getName().compareTo(o2.getName()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortType(ActionMapping mapping,
                                  ActionForm form,
                                  final HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        calcDirection(request, "taskType");
        return sortResults(mapping, request, new Comparator<Activity>() {
            public int compare(Activity o1, Activity o2) {
                return o1.getTaskStateMachine().toString().compareTo(o2.getTaskStateMachine().toString()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortStatus(ActionMapping mapping,
                                    ActionForm form,
                                    final HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {
        calcDirection(request, "status");
        return sortResults(mapping, request, new Comparator<Activity>() {
            public int compare(Activity o1, Activity o2) {
                return o1.getStatus().toString().compareTo(o2.getStatus().toString()) * sortDirection(request);
            }
        });
    }
    
    public ActionForward sortResponsible(ActionMapping mapping,
                                         ActionForm form,
                                         final HttpServletRequest request,
                                         HttpServletResponse response) throws Exception {
        calcDirection(request, "responsible");
        return sortResults(mapping, request, new Comparator<Activity>() {
            public int compare(Activity o1, Activity o2) {
                return 0;//o1.getResponsible().compareTo(o2.getResponsible()) * sortDirection(request);
            }
        });
    }

    private SearchLocal lookupSearchBean() {
        try {
            Context c = new InitialContext();
            return (SearchLocal) c.lookup("java:comp/env/SearchBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private ContactableLocal lookupContactableBean() {
        try {
            Context c = new InitialContext();
            return (ContactableLocal) c.lookup("java:comp/env/ContactableBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private NodeLocal lookupNodeBean() {
        try {
            Context c = new InitialContext();
            return (NodeLocal) c.lookup("java:comp/env/NodeBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }
    
}
